# coding=utf-8

# 该服务提供id获取服务

#加载配置文件
import  config
#加载函数库
from base_fun import base_fun;
#加载系统模块
import socket, select,time,random,sys;
#加载mysql数据库
import MySQLdb;

#声明全局变量
db_hash = config.db_hash;
table_hash = config.table_hash;

#数据库配置
db_host = config.get_id_db_host;
db_user = config.get_id_db_user;
db_pwd = config.get_id_db_pwd;
db_name= config.get_id_db_name;
db_get_sql = config.get_id_db_get_sql;

#初始化变量
db_no =0 ;
table_no =0;

#初始化插入id
insert_id = 0;

#初始化连接数据库
db_lock = 1;

#初始化基础函数
base_fun = base_fun(config.error_msg);

try:
	#数据库初始化连接
	con=MySQLdb.Connection(db_host,db_user,db_pwd,db_name);
	db =  con.cursor();
except MySQLdb.Error, e:
	print "Error %d: %s" % (e.args[0], e.args[1])
	sys.exit (1)


serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
serversocket.bind(('0.0.0.0', config.get_id_port));
serversocket.listen(1);
serversocket.setblocking(0);

epoll = select.epoll();
epoll.register(serversocket.fileno(), select.EPOLLIN );

try:
	connections = {}; requests = {};
	while True:
		while True:
			events = epoll.poll(-1);
			#print("s");
			for fileno, event in events:
				if fileno == serversocket.fileno():
					connection, address = serversocket.accept();
					connection.setblocking(0);
					epoll.register(connection.fileno(), select.EPOLLIN );
					connections[connection.fileno()] = connection;
					requests[connection.fileno()] = b"";
				elif event & select.EPOLLIN:
					try:
						#接受头信息
						requests[fileno] = connections[fileno].recv(config.head_len);
					
						#关闭连接
						if len(requests[fileno]) ==0:
							raise ;

						temp_list = base_fun.pase_cmd_head(requests[fileno]);
						#取得命令
						cmd_no = temp_list[0];
						#内容长度
						body_len = temp_list[1];
						#内容长度解析错误处理
						if body_len>65535 or body_len<0:
							#发送返回信息
							connections[fileno].send(base_fun.build_cmd(-1000,base_fun.get_error_msg(-1000)));
							#触发异常
							raise ;
						#处理内容接收
						requests[fileno] +=connections[fileno].recv(body_len);
						while len(requests[fileno])<body_len:
							requests[fileno] +=connections[fileno].recv(1);
						body_info = base_fun.pase_body(requests[fileno],config.head_len,body_len);
						
						#获取自增id
						if cmd_no ==1001:
							#设置当前变量
							cur_db = db_no % len(table_hash);
							cur_table = table_no % len(table_hash);
							#id自增实现轮播
							table_no +=1;
							if table_no % len(table_hash) == 0:
								db_no = db_no+1;
								db_lock = 1;
							if db_no % len(db_hash) ==0 and db_lock==1: 
								#取得用户库id
								db.execute(db_get_sql);
								insert_id=con.insert_id();
								db_lock =0;
							#拼装返回字符串
							#return_str = db_hash[cur_db]+table_hash[cur_table]+str(insert_id);
							return_str = {"db":db_hash[cur_db],'tb':table_hash[cur_table],'id':insert_id};
							send_list = base_fun.build_cmd(1002,return_str);
							connections[fileno].send(send_list);
							
							#返回循环
							epoll.modify(fileno, select.EPOLLIN);
						else:
							#发送返回信息
							connections[fileno].send(base_fun.build_cmd(-1001,base_fun.get_error_msg(-1001)));
							#触发异常
							raise ;
					except:
						#关闭连接
						connections[fileno].shutdown(socket.SHUT_RDWR);
						epoll.unregister(fileno);
						connections[fileno].close();
						del connections[fileno];
finally:
	epoll.unregister(serversocket.fileno());
	epoll.close();
	serversocket.close();

